home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-04-10 | 19.6 KB | 718 lines | [TEXT/MPS ] |
- /*---------------------------------------------------------------------------
- FILENAME
- OldAPIMessageIntf.c
-
- DESCRIPTION
- This module contains the routines which implement the old API messages
- that the ImageWriter LQ driver overrides. Much of the logic in this
- module was gleaned from the original ImageWriter LQ driver, and so
- some of the calculations may seem a little strange. In order to maintain
- compatibility with the old driver's logic, we must preserve much of the
- old logic.
-
- COPYRIGHT
- Copyright Apple Computer, Inc. 1992-1994
- All rights reserved.
-
- INTERFACE ROUTINES:
-
- SD_PrValidate
- SD_ConvertPrintRecordTo
- SD_ConvertPrintRecordFrom
-
- 12/20/93 - dmh - Sync'd with the shipping 1.0b3 GX driver.
- 8/28/94 - dmh - Sync'd with the shipping 1.0.1 GX driver.
-
- -------------------------------------------------------------------------------- */
-
- // Include the standard Mac header files
- #include "MacIncludes.h"
-
- // Include the new QuickDraw GX graphics header files
- #include <graphics routines.h>
- #include <graphics libraries.h>
- #include <math routines.h>
-
- // Include the required Printing Manager header files
- #include <PrintingManager.h>
- #include <PrintingMessages.h>
- #include <PrintingDrivers.h>
- #include <Collections.h>
- #include <Messages.h>
- #include <PrintingResTypes.h>
- #include <PrintingErrors.h>
- #include <GXExceptions.h>
-
- // Include the internal driver constants and types used by this module
- #include "Resources.h"
- #include "OldAPIMessageIntf.h"
-
-
- /***************************************************************************************
- * INTERNAL ROUTINES *
- ***************************************************************************************/
-
-
- /****************************************************************************************
-
- OldLQ_CiMetrics
-
- function:
- This function takes an old style print record and massages its fields in
- a manner equivalent to the old style LQ driver. This logic is basically
- lifted from the old LQ driver.
-
- parameters:
- hPrint target print record whose fields are to be updated
-
- returns:
- none
-
- ****************************************************************************************/
- void OldLQ_CiMetrics(THPrint hPrint)
- {
- TPPrint pPrint = *hPrint;
- short dhPage;
- short dvPage;
- short dhPaper;
- short dvPaper;
- short hOff;
- short vOff;
- short cPlaten;
- short gap;
- short scanBits;
- short maxH;
- short wDev;
-
- cPlaten = kPlaten8;
- if ( pPrint->prStl.iPageH > (9 * kMysticPaperFract) )
- {
- cPlaten = kPlaten15; // platen width in half inches
- }
-
- wDev = pPrint->printX[1];
- pPrint->prInfo.iDev = 0; // Use screen device for lo res or fake hi res
- if ( !TestBit(wDev, kResSetBit) ) // not fResSet
- {
- pPrint->prInfo.iVRes = 72;
- pPrint->prInfo.iHRes = 72;
- }
- else
- if ( pPrint->prInfo.iVRes == 216 ) // Real HiRes
- {
- wDev |= kHighResBit; // force "hi res"
- wDev &= ~k66PercentReducBit; // clear 66% Reduction off
- wDev &= ~k33PercentReducBit; // clear 33% Reduction off
- pPrint->printX[1] = wDev;
- }
-
- // Calculate rPaper height in Y
- dvPaper = (pPrint->prStl.iPageV * pPrint->prInfo.iVRes) / kMysticPaperFract;
-
- // Calculate rPage height in Y
- gap = (60 * pPrint->prInfo.iVRes) / kMysticPaperFract;
-
- if ( TestBit(wDev, kScrollBit) )
- {
- gap = 0;
- }
-
- // force page height to be an integral number of head scans
- dvPage = (( dvPaper - gap ) / 24) * 24;
-
- // Calculate rPaper width in dots
- dhPaper = (pPrint->prStl.iPageH * pPrint->prInfo.iHRes) / kMysticPaperFract;
-
- // Calculate max width in dots
-
- maxH = ( cPlaten * pPrint->prInfo.iHRes ) >> 1;
- if (maxH > dhPaper)
- {
- maxH = dhPaper;
- }
- scanBits = ( maxH >> 4 ) << 4; // force to word boundary
-
- if ( TestBit(pPrint->prStl.wDev, kPortraitBit) ) // Portrait orientation
- {
- dhPage = scanBits;
- }
- else // Landscape orientation: switch height and width
- {
- dhPage = dvPage;
- dvPage = scanBits;
- }
-
- SetRect(&pPrint->prInfo.rPage, 0, 0, dhPage, dvPage);
-
- // Calculate rPaper offsets, & set rPaper
-
- if ( TestBit(pPrint->prStl.wDev, kPortraitBit) ) // Portrait orientation
- {
- hOff = (dhPage - dhPaper) >> 1; // Note: Negative
- vOff = -gap;
- }
- else // Landscape orientation: switch height and width
- {
- short iTemp;
-
- iTemp = dhPaper;
- dhPaper = dvPaper;
- dvPaper = iTemp;
-
- hOff = - gap;
- vOff = (dvPage - dvPaper) >> 1;
- }
- SetRect(&pPrint->rPaper, hOff, vOff, dhPaper + hOff, dvPaper + vOff);
-
- // Calculate rPage height in dots, & set rPage
- //If 66% reduction, triple both rectangles: ( Page and Paper )
-
- if ( TestBit(wDev, k66PercentReducBit) ) // 66% reduction selected
- {
- pPrint->prInfo.rPage.right *= 3;
- pPrint->prInfo.rPage.bottom *= 3;
-
- pPrint->rPaper.top *= 3;
- pPrint->rPaper.left *= 3;
- pPrint->rPaper.right *= 3;
- pPrint->rPaper.bottom *= 3;
- }
-
- // If 33% reduction, scale both rectangles: ( Page and Paper )
- if ( TestBit(wDev, k33PercentReducBit) ) // 33% reduction selected
- {
- pPrint->prInfo.rPage.right = FixRound( FixMul( lScale, (pPrint->prInfo.rPage.right << 16) ));
- pPrint->prInfo.rPage.bottom = FixRound( FixMul( lScale, (pPrint->prInfo.rPage.bottom << 16) ));
-
- pPrint->rPaper.top = FixRound( FixMul( lScale, (pPrint->rPaper.top << 16) ));
- pPrint->rPaper.left = FixRound( FixMul( lScale, (pPrint->rPaper.left << 16) ));
- pPrint->rPaper.right = FixRound( FixMul( lScale, (pPrint->rPaper.right << 16) ));
- pPrint->rPaper.bottom = FixRound( FixMul( lScale, (pPrint->rPaper.bottom << 16) ));
- }
-
- if ( TestBit(wDev, kDraftBit) ) // Draft bits selected
- {
- pPrint->prJob.bJDocLoop = bDraftLoop;
- }
-
- // Copy WDEV field back to old position for apps that read these flags
-
- if ( TestBit(pPrint->prStl.wDev, kPortraitBit) )
- {
- wDev |= kPortraitBit;
- }
- else
- {
- wDev &= ~kPortraitBit;
- }
-
- pPrint->printX[1] = wDev;
- pPrint->prStl.wDev = wDev;
- }
- /* OldLQ_CiMetrics */
-
-
- /****************************************************************************************
-
- OldLQ_CiXMetrics
-
- function:
- This function takes an old style print record and massages the PrInfoPT and
- PrXInfo fields in a manner equivalent to the old style LQ driver. This logic
- is basically lifted from the old LQ driver.
-
- parameters:
- hPrint target print record whose fields are to be updated
-
- returns:
- none
-
- ****************************************************************************************/
- void OldLQ_CiXMetrics(THPrint hPrint)
- {
- TPPrint pPrint = *hPrint;
- short iScans;
- short iDevExtra;
-
- pPrint->prInfoPT = pPrint->prInfo; // Start with a straight copy
-
- pPrint->prXInfo.bPatScale = 0;
-
- if ( !TestBit(pPrint->prStl.wDev, kPortraitBit) ) // Landscape mode
- {
- pPrint->prJob.bJDocLoop = bSpoolLoop; // Force spooling for landscape
- }
-
- if ( TestBit(pPrint->printX[1], k66PercentReducBit) || TestBit(pPrint->printX[1], k33PercentReducBit) ) // 33% or 66% reduction
- {
- pPrint->printX[1] &= ~kHighResBit; // Clear the high-res bit
-
- if ( TestBit(pPrint->printX[1], k33PercentReducBit) ) // If 33% Reduction ONLY
- {
- pPrint->prXInfo.bPatScale = 2; // Pattern double
-
- // SCALE 2X FOR 33% REDUCTION CASE
- pPrint->prInfoPT.rPage.right <<= 1;
- pPrint->prInfoPT.rPage.bottom <<= 1;
- }
- }
-
- if ( TestBit(pPrint->printX[1], kHighResBit) ) // High resolution; triple everything
- {
- if ( !TestBit(pPrint->printX[1], kResSetBit) ) // App hasn't set imaging resolution
- {
- pPrint->prInfoPT.iHRes *= 3;
- pPrint->prInfoPT.iVRes *= 3;
- pPrint->prInfoPT.rPage.right *= 3;
- pPrint->prInfoPT.rPage.bottom *= 3;
- }
-
- pPrint->prXInfo.bPatScale = 3; // Pattern triple ** NOT VALID QD ** Intercept in PrBand
- pPrint->prInfoPT.iDev = 0xFD00; // For QD's char spacing adjustment
- }
-
- if ( TestBit(pPrint->prStl.wDev, kPortraitBit) ) // Portrait mode
- {
- pPrint->prXInfo.iBandH = pPrint->prInfoPT.rPage.right;
- pPrint->prXInfo.iBandV = 48; // i8xBandScans = 24 * 2
- iScans = pPrint->prInfoPT.rPage.bottom;
- pPrint->prXInfo.scan = scanTop2Bottom;
- iDevExtra = pPrint->prXInfo.iBandH;
- }
- else // Landscape mode
- {
- pPrint->prXInfo.iBandH = 48; // i8xBandScans = 24 * 2;
- pPrint->prXInfo.iBandV = pPrint->prInfoPT.rPage.bottom;
- iScans = pPrint->prInfoPT.rPage.right;
- pPrint->prXInfo.scan = scanLeft2Right;
- iDevExtra = pPrint->prXInfo.iBandV;
- }
-
- pPrint->prXInfo.iRowBytes = pPrint->prXInfo.iBandH >> 3; // Must be even!
- pPrint->prXInfo.iBands = ( iScans + 48 - 1 ) / 48;
-
- // Size a scan work buffer
- pPrint->prXInfo.iDevBytes = ( pPrint->prXInfo.iRowBytes * pPrint->prXInfo.iBandV ) + ( iDevExtra * 3 );
-
- // Copy WDEV field back to old position for apps that read these flags
- pPrint->prStl.wDev = pPrint->printX[1];
- }
- /* OldLQ_CiXMetrics */
-
-
- /****************************************************************************************
-
- UpdatePrintRecord
-
- function:
- This function updates the print record based upon the application's
- calls to PrGeneral.
-
- parameters:
- hPrint print record to update
-
- returns:
- none
-
- ****************************************************************************************/
- void UpdatePrintRecord(THPrint hPrint)
- {
- // emulate the old metric calculations
- OldLQ_CiMetrics(hPrint);
- OldLQ_CiXMetrics(hPrint);
- }
- /* UpdatePrintRecord */
-
-
-
- /***************************************************************************************
- * INTERFACE ROUTINES *
- ***************************************************************************************/
-
- /****************************************************************************************
-
- SD_PrValidate
-
- function:
- This function validates the print record. If the passed-in print record contains
- valid information (see below), then it's updated based upon the application's
- calls to PrGeneral and the return code is true.
- Otherwise, the print record is defaulted (with PrintDefault), and the
- return value is false.
-
- Validation:
- The upper byte of the PrintX[1] field must be the ID of the device
- (kLQRefNum in OldAPIMessageIntf.h).
-
- The version of the print record must be current
- (oldIWLQPrintRecordVersion in Resources.h)
-
- (For new print records, we will validate all of the fields which are
- public (e.g., paper size), not just these fields)
-
- parameters:
- hPrint print record to validate
- wasChanged returns true if print record was invalid; false otherwise
-
- returns:
- OSErr
-
- ****************************************************************************************/
- OSErr SD_PrValidate(THPrint hPrint, Boolean *wasChanged)
- {
- short wDev; // device specific stuff in this word
- Boolean returnVal = true; // initialize return value to "invalid"
- // Why is true == "invalid"? Nobody knows!
-
- // check the wDev. The upper byte must be equal to kLQRefNum. We get the
- // wDev, and shift wDev DOWN eight.
-
- wDev = (*hPrint)->printX[1];
- wDev >>= 8; // get just the device ID
-
-
- // If the device id is equal, then check the version number of the print record.
- // Only if that is also equal to the current version, will we return false (valid).
-
- if (wDev == kLQRefNum)
- if ( (*hPrint)->iPrVersion == oldIWLQPrintRecordVersion )
- returnVal = false;
-
-
- // If the print record is not valid, then return the default print record.
- // Otherwise, update the print record, based on the application's calls
- // to PrGeneral.
-
- if (returnVal)
- PrintDefault(hPrint);
- else
- UpdatePrintRecord(hPrint);
-
- *wasChanged = returnVal;
-
- return(noErr);
- }
- /* SD_PrValidate */
-
-
- /****************************************************************************************
-
- SD_ConvertPrintRecordTo
-
- function:
- SD_ConvertPrintRecordTo converts the fields of the print record for
- the device into the universal print record format.
-
- parameters:
- hPrint print record to convert to universal format
-
- returns:
- OSErr
-
- ****************************************************************************************/
- OSErr SD_ConvertPrintRecordTo(THPrint hPrint)
- {
- gxUniversalPrintRecordPtr pUniv;
- TPPrint pPrint;
- short options = 0;
-
- pUniv = (gxUniversalPrintRecordPtr) *hPrint;
- pPrint = *hPrint;
-
- // Convert paper feed settings (old and univ setting are switched)
-
- if ( pPrint->prStl.feed == oldPRECAutoFeed )
- pUniv->feed = gxAutoFeed;
- else
- pUniv->feed = gxManualFeed;
-
- // Fix up the actualCopies field
- pUniv->actualCopies = pPrint->prJob.iCopies;
-
- // Determine the new options field settings
-
- if ( TestBit(pPrint->prStl.wDev, kScrollBit) )
- options |= gxBiggerPages;
-
- pUniv->options = options;
-
-
- // Now determine the scaling factor, if any, and designate the proper dialog button that
- // corresponds to the scaling factor. The userCluster1 field specifies the dialog button.
-
- if ( TestBit(pPrint->prStl.wDev, k66PercentReducBit) )
- {
- pUniv->reduction = 66;
- pUniv->userCluster1 = 1;
- }
- else
- if ( TestBit(pPrint->prStl.wDev, k33PercentReducBit) )
- {
- pUniv->reduction = 33;
- pUniv->userCluster1 = 0;
- }
- else // T => No scaling being performed
- {
- pUniv->reduction = 100;
- pUniv->userCluster1 = 2;
- }
-
-
- // Set the orientation properly
-
- if ( TestBit(pPrint->prStl.wDev, kPortraitBit) )
- pUniv->orientation = gxPortraitOrientation;
- else
- pUniv->orientation = gxLandscapeOrientation;
-
-
- // Determine the quality setting
-
- if ( TestBit(pPrint->prStl.wDev, kHighResBit) ) // T => Print in best quality
- {
- pUniv->qualityMode = gxBestQuality;
- }
- else
- if ( pPrint->prJob.bJDocLoop == spool ) // T => Print with faster quality
- {
- pUniv->qualityMode = gxFasterQuality;
- }
- else // T => Print with draft quality
- pUniv->qualityMode = gxDraftQuality;
-
-
- // Set the first tray and remaining tray fields
-
- if ( (pPrint->printX[0] & 0x0003) > 0 ) // T => A first tray has been specified
- {
- switch ( pPrint->printX[0] & 0x0003 )
- {
- case tray1: pUniv->firstTray = gxFirstTray; break;
- case tray2: pUniv->firstTray = gxSecondTray; break;
- case tray3: pUniv->firstTray = gxThirdTray; break;
- default: pUniv->firstTray = gxFirstTray; break;
- }
- }
- else
- pUniv->firstTray = gxFirstTray;
-
- if ( (pPrint->printX[0] & 0x000C) > 0 ) // T => A remaining tray has been specified
- {
- switch ( pPrint->printX[0] & 0x000C )
- {
- case tray1: pUniv->remainingTray = gxFirstTray; break;
- case tray2: pUniv->remainingTray = gxSecondTray; break;
- case tray3: pUniv->remainingTray = gxThirdTray; break;
- default: pUniv->remainingTray = gxFirstTray; break;
- }
- }
- else
- pUniv->remainingTray = gxFirstTray;
-
-
- // Set the headMotion field's value
-
- if ( TestBit(pPrint->prStl.wDev, kBiDirBit) ) // T => Print in bidirectional mode
- {
- pUniv->headMotion = gxBidirectionalMotion;
- }
- else
- pUniv->headMotion = gxUnidirectionalMotion;
-
-
- // Always assign these fields explicit values to ensure they don't cause problems
-
- pUniv->coverPage = gxNoCoverPage;
- pUniv->saveFile = gxNoFile;
-
- return(noErr);
- }
- /* SD_ConvertPrintRecordTo */
-
-
- /****************************************************************************************
-
- SD_ConvertPrintRecordFrom
-
- function:
- SD_ConvertPrintRecordFrom converts the fields of the print record in
- universal print record format into the print record format for the
- specific device.
-
- parameters:
- hPrint print record to convert to device specific format
-
- returns:
- OSErr
-
- ****************************************************************************************/
- OSErr SD_ConvertPrintRecordFrom(THPrint hPrint)
- {
- gxUniversalPrintRecordPtr pUniv;
- TPPrint pPrint;
- short newWDev = kLQRefNum << 8;
-
- pUniv = (gxUniversalPrintRecordPtr) *hPrint;
- pPrint = *hPrint;
-
- // Convert paper feed settings (old and univ setting are switched)
-
- if ( pUniv->feed == gxAutoFeed )
- pPrint->prStl.feed = oldPRECAutoFeed;
- else
- pPrint->prStl.feed = oldPRECManualFeed;
-
-
- // Fix up the actualCopies field
- pPrint->prJob.iCopies = pUniv->actualCopies;
-
-
- // Determine the new wDev flag settings
-
- if ( TestBit(pUniv->options, gxBiggerPages) )
- newWDev |= kScrollBit;
-
- if (pUniv->headMotion == gxBidirectionalMotion)
- newWDev |= kBiDirBit;
-
- switch( pUniv->userCluster1 ) // Based on the scaling dialog button setting, set the scaling factor
- {
- case 2: // Full size
- break;
-
- case 1:
- newWDev |= k66PercentReducBit;
- break;
-
- case 0:
- newWDev |= k33PercentReducBit;
- break;
- }
-
- if (pUniv->orientation == gxPortraitOrientation)
- newWDev |= kPortraitBit;
-
- if (pUniv->qualityMode == gxBestQuality)
- {
- newWDev |= kHighResBit;
- pPrint->prJob.bJDocLoop = spool;
- }
- else
- if (pUniv->qualityMode == gxFasterQuality)
- {
- pPrint->prJob.bJDocLoop = spool;
- }
- else // T => Draft quality
- {
- newWDev |= kDraftBit;
- pPrint->prJob.bJDocLoop = draft;
- }
-
- // set the bit to indicate SetResolution has been called, if the resolution is already 216
- if ( pPrint->prInfo.iVRes == 216)
- newWDev |= kResSetBit;
-
- // Update the wDev field and the printX[1] field (a copy of wDev)
- pPrint->prStl.wDev = newWDev;
- pPrint->printX[1] = newWDev;
-
-
- // Fix up the tray settings
- {
- short firstTrayNum = tray1;
- short remainingTrayNum = tray1;
-
- switch (pUniv->firstTray)
- {
- case gxFirstTray: firstTrayNum = tray1; break;
- case gxSecondTray: firstTrayNum = tray2; break;
- case gxThirdTray: firstTrayNum = tray3; break;
- }
-
- switch (pUniv->remainingTray)
- {
- case gxFirstTray: remainingTrayNum = tray1; break;
- case gxSecondTray: remainingTrayNum = tray2; break;
- case gxThirdTray: remainingTrayNum = tray3; break;
- }
-
- pPrint->printX[0] = (remainingTrayNum << 2) | firstTrayNum;
- }
-
- // Initialize some of the remaining fields in the TPrXInfo structure. PrValidate will fill in the rest
-
- pPrint->prXInfo.bUlThick = 0;
- pPrint->prXInfo.bUlOffset = 0;
- pPrint->prXInfo.bUlShadow = 0;
- pPrint->prXInfo.bXInfoX = 0;
-
- return(noErr);
- }
- /* SD_ConvertPrintRecordFrom */
-
-
- /****************************************************************************************
-
- SD_PrintRecordToJob
-
- function:
- SD_PrintRecordToJob is called by the Printing Manager when a print record
- needs to be converted into a job. This driver takes this opportunity to
- add two collection items to the job, namely the one which specifies the
- desired head motion and the users tray selection.
-
- parameters:
- hPrint print record to convert to a job
- theJob job reference to use in converting the print record
-
- returns:
- OSErr
-
- ****************************************************************************************/
- OSErr SD_PrintRecordToJob(THPrint hPrint, gxJob theJob)
- {
- OSErr anErr;
-
- // First forward the message so the job is created
- anErr = Forward_GXPrintRecordToJob(hPrint, theJob);
- require(anErr == noErr, Forward_GXPrintRecordToJob);
-
- // Add the collection item which specifies the desired head motion
- {
- HeadMotionJobItem theMotion;
-
- theMotion.direction = (!TestBit((*hPrint)->prStl.wDev, kBiDirBit)) ? doUnidirectional : doBidirectional;
-
- anErr = AddCollectionItem( GXGetJobCollection(theJob),
- kDrvrCreatorType,
- kHeadMotionItemIndex,
- sizeof(HeadMotionJobItem),
- &theMotion);
- require(anErr == noErr, AddHeadMotion);
- }
-
-
- // Add the collection item which specifies the desired tray settings
- {
- TraySettingsJobItem theTraySettings;
-
- theTraySettings.firstPageFromTray = (*hPrint)->printX[0] & 0x0003;
- theTraySettings.remainingFromTray = ((*hPrint)->printX[0] & 0x000C) >> 2;
-
- anErr = AddCollectionItem( GXGetJobCollection(theJob),
- kDrvrCreatorType,
- kTraySettingsItemIndex,
- sizeof(TraySettingsJobItem),
- &theTraySettings);
- require(anErr == noErr, AddTraySettings);
- }
-
-
- /******* Clean-up *******/
-
- AddHeadMotion:
- AddTraySettings:
- Forward_GXPrintRecordToJob:
- return(anErr);
- }
- /* SD_PrintRecordToJob */